package com.q3d.demo.api.user.client.feign;

import com.q3d.demo.api.user.service.UserBaseServiceInterface;
import com.q3d.demo.common.lib.service.dto.CountResultDto;
import com.q3d.demo.common.lib.service.dto.IdExtDto;
import com.q3d.demo.common.lib.service.dto.IdExtListDto;
import com.q3d.demo.common.lib.service.dto.OpResultDto;
import com.q3d.demo.common.lib.service.dto.PageRequestDto;
import com.q3d.demo.common.lib.service.dto.StringDto;
import com.q3d.demo.common.lib.service.dto.UuidDto;
import com.q3d.demo.common.lib.service.dto.UuidListDto;
import com.q3d.demo.common.lib.service.response.ResponseBase;
import com.q3d.demo.common.lib.service.response.ResponseFeignDecoder;
import com.q3d.demo.api.user.dto.UserBaseP1Dto;
import com.q3d.demo.api.user.dto.UserBaseP1K1Dto;
import com.q3d.demo.api.user.dto.UserBaseP1K2Dto;
import com.q3d.demo.api.user.dto.UserBaseP1ListDto;
import com.q3d.demo.api.user.dto.UserBaseR1K1Dto;
import com.q3d.demo.api.user.dto.UserBaseR1K1ListDto;
import com.q3d.demo.api.user.dto.UserBaseR1K2Dto;
import com.q3d.demo.api.user.dto.UserBaseR1K2ListDto;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

@Service
@Validated /** Controller 中某些接口的入参可能没有封装 DTO 进行校验，因此在 Service 层再做一次校验 */
/**
 * 远程接口的具体实现：Feign 调用
 * 
 * @author 叶湘 ( weixin:yexiang841, email:yexiang841@qq.com )
 */
public class UserBaseClientFeign implements UserBaseServiceInterface {

        @Autowired
        private UserBaseFeignInterface feignInterface;

        @Override
        public StringDto hello(@Valid StringDto dtoStringRequest) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(StringDto.class);
                // 此处是远程调用
                ResponseBase<StringDto> result = feignInterface.hello(dtoStringRequest.getText());
                return result.getData();
        }

        @Override
        public UuidDto addOne(UserBaseP1Dto helloWorldP1dto) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(UuidDto.class);
                // 此处是远程调用
                ResponseBase<UuidDto> result = feignInterface.addOne(helloWorldP1dto);
                return result.getData();
        }

        @Override
        public UuidListDto addBatch(@Valid UserBaseP1ListDto dtoP1List) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(UuidListDto.class);
                // 此处是远程调用
                ResponseBase<UuidListDto> result = feignInterface.addBatch(dtoP1List);
                return result.getData();
        }

        @Override
        public OpResultDto removeOne(@Valid UuidDto dtoUuid) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(OpResultDto.class);
                // 此处是远程调用
                ResponseBase<OpResultDto> result = feignInterface.removeOne(dtoUuid.getUuid());
                return result.getData();
        }

        @Override
        public OpResultDto removeBatch(@Valid UuidListDto dtoUuidList) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(OpResultDto.class);
                // 此处是远程调用
                ResponseBase<OpResultDto> result = feignInterface.removeBatch(dtoUuidList);
                return result.getData();
        }

        @Override
        public OpResultDto deleteOne(@Valid IdExtDto dtoIdExt) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(OpResultDto.class);
                // 此处是远程调用
                ResponseBase<OpResultDto> result = feignInterface.deleteOne(dtoIdExt.getIdExt());
                return result.getData();
        }

        @Override
        public OpResultDto deleteBatch(@Valid IdExtListDto dtoIdExtList) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(OpResultDto.class);
                // 此处是远程调用
                ResponseBase<OpResultDto> result = feignInterface.deleteBatch(dtoIdExtList);
                return result.getData();
        }

        @Override
        public OpResultDto reviveOne(@Valid IdExtDto dtoIdExt) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(OpResultDto.class);
                // 此处是远程调用
                ResponseBase<OpResultDto> result = feignInterface.reviveOne(dtoIdExt.getIdExt());
                return result.getData();
        }

        @Override
        public OpResultDto reviveBatch(@Valid IdExtListDto dtoIdExtList) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(OpResultDto.class);
                // 此处是远程调用
                ResponseBase<OpResultDto> result = feignInterface.deleteBatch(dtoIdExtList);
                return result.getData();
        }

        @Override
        public OpResultDto editSelective(@Valid UserBaseP1K1Dto dtoP1K1) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(OpResultDto.class);
                // 此处是远程调用
                ResponseBase<OpResultDto> result = feignInterface.editSelective(dtoP1K1);
                return result.getData();
        }

        @Override
        public OpResultDto updateSelective(@Valid UserBaseP1K2Dto dtoP1K2) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(OpResultDto.class);
                // 此处是远程调用
                ResponseBase<OpResultDto> result = feignInterface.updateSelective(dtoP1K2);
                return result.getData();
        }

        @Override
        public CountResultDto getCount() {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(CountResultDto.class);
                // 此处是远程调用
                ResponseBase<CountResultDto> result = feignInterface.getCount();
                return result.getData();
        }

        @Override
        public UserBaseR1K1Dto getOne(@Valid UuidDto dtoUuid) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(UserBaseR1K1Dto.class);
                // 此处是远程调用
                ResponseBase<UserBaseR1K1Dto> result = feignInterface.getOne(dtoUuid.getUuid());
                return result.getData();
        }

        @Override
        public UserBaseR1K1ListDto getBatch(@Valid UuidListDto dtoUuidList) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(UserBaseR1K1ListDto.class);
                // 此处是远程调用
                ResponseBase<UserBaseR1K1ListDto> result = feignInterface.getBatch(dtoUuidList);
                return result.getData();
        }

        @Override
        public UserBaseR1K1ListDto getByPage(@Valid PageRequestDto dtoPageRequest) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(UserBaseR1K1ListDto.class);
                // 此处是远程调用
                ResponseBase<UserBaseR1K1ListDto> result = feignInterface.getByPage(dtoPageRequest);
                return result.getData();
        }

        @Override
        public UuidListDto getUuidByPage(@Valid PageRequestDto dtoPageRequest) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(UuidListDto.class);
                // 此处是远程调用
                ResponseBase<UuidListDto> result = feignInterface.getUuidByPage(dtoPageRequest);
                return result.getData();
        }

        @Override
        public CountResultDto selectCount() {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(CountResultDto.class);
                // 此处是远程调用
                ResponseBase<CountResultDto> result = feignInterface.selectCount();
                return result.getData();
        }

        @Override
        public CountResultDto selectCountRemoved() {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(CountResultDto.class);
                // 此处是远程调用
                ResponseBase<CountResultDto> result = feignInterface.selectCountRemoved();
                return result.getData();
        }

        @Override
        public UserBaseR1K2Dto selectOne(@Valid IdExtDto dtoIdExt) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(UserBaseR1K2Dto.class);
                // 此处是远程调用
                ResponseBase<UserBaseR1K2Dto> result = feignInterface.selectOne(dtoIdExt.getIdExt());
                return result.getData();
        }

        @Override
        public UserBaseR1K2ListDto selectBatch(@Valid IdExtListDto dtoIdExtList) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(UserBaseR1K2ListDto.class);
                // 此处是远程调用
                ResponseBase<UserBaseR1K2ListDto> result = feignInterface.selectBatch(dtoIdExtList);
                return result.getData();
        }

        @Override
        public UserBaseR1K2ListDto selectByPage(@Valid PageRequestDto dtoPageRequest) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(UserBaseR1K2ListDto.class);
                // 此处是远程调用
                ResponseBase<UserBaseR1K2ListDto> result = feignInterface.selectByPage(dtoPageRequest);
                return result.getData();
        }

        @Override
        public IdExtListDto selectIdExtByPage(@Valid PageRequestDto dtoPageRequest) {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(IdExtListDto.class);
                // 此处是远程调用
                ResponseBase<IdExtListDto> result = feignInterface.selectIdExtByPage(dtoPageRequest);
                return result.getData();
        }

        @Override
        public IdExtListDto selectIdExtRemoved() {
                // Feign 不能处理泛型响应结构体，因此为自定义解码器设定类型
                ResponseFeignDecoder.setReturnType(IdExtListDto.class);
                // 此处是远程调用
                ResponseBase<IdExtListDto> result = feignInterface.selectIdExtRemoved();
                return result.getData();
        }

}
